//
//  RoomScheduleViewController.m
//  mUBB
//
//  Created by Cosmin Stirbu on 3/13/13.
//  Copyright (c) 2013 Cosmin Stirbu. All rights reserved.
//

#import "RoomScheduleViewController.h"
#import "KalLogic.h"
#import "UIViewAdditions.h"
#import "Constants.h"
#import "KalDate.h"
#import "BookingsManager.h"
#import "NSDateAdditions.h"
#import "WSError.h"

#define DATE_FORMAT @"EE dd - MMM - yyyy"
#define KAL_VIEW_Y (IS_IPAD () ? 136 : 45)
#define KAL_VIEW_WIDTH (IS_IPAD () ? 420 : 320)
#define KAL_VIEW_HEIGHT (IS_IPAD () ? 295 : 266)


#define TEACHER_ACTION_SHEET 1
#define REGULAR_USER_ACTION_SHEET 2
#define FUTURE_BOOKINGS_ACTION_SHEET 3

@interface RoomScheduleViewController ()

@end

@implementation RoomScheduleViewController

@synthesize dateButton, dateToolbar, selectedDateButton, horizontalScrollView;

- (id)initWithNibName:(NSString *)nibNameOrNil room:(Room *)room
{
    self = [super initWithNibName:nibNameOrNil bundle:nil];
    if (self) {
        // Custom initialization
        _bookingsDictionary = [NSMutableDictionary new];
        _room = room;
        _selectedDate = [NSDate date];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    // Today Button
    UIBarButtonItem *todayButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"TODAY_BUTTON_TITLE", nil) style:UIBarButtonItemStyleBordered target:self action:@selector(goToToday)];
    self.navigationItem.rightBarButtonItem = todayButton;
    
    // Set Up The UI
    dateToolbar.tintColor = self.navigationController.navigationBar.tintColor;
    selectedDateButton.title = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
    dateButton.title = NSLocalizedString(@"DATE_BUTTON_TITLE", nil);
    
    // Scroll View
    horizontalScrollView.contentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width * 3, 0);
    horizontalScrollView.contentOffset = CGPointMake([UIScreen mainScreen].bounds.size.width, 0);
    _previousDateView.left = 0;
    _currentDateView.left = [UIScreen mainScreen].bounds.size.width;
    _nextDateView.left = [UIScreen mainScreen].bounds.size.width * 2;
    
    
    // Delegate
    _previousDateView.delegate = self;
    _currentDateView.delegate = self;
    _nextDateView.delegate = self;
    
    // Get Dates
    [self getDates];
    

}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self okPressedOnCalendar:nil];
}

#pragma mark - Private Methods

- (void)getDates {
    [Utils showLoadingOn:self];
    _allDates = YES;
    // Get Dates
    _previousDate = [_selectedDate previousDay];
    _nextDate = [_selectedDate nextDay];
    _requestsCounter += 3;
    [[BookingsManager instance] getBookingsForRoom:_room withDate:_previousDate delegate:self].info = _previousDate;
    [[BookingsManager instance] getBookingsForRoom:_room withDate:_selectedDate delegate:self].info = _selectedDate;
    [[BookingsManager instance] getBookingsForRoom:_room withDate:_nextDate delegate:self].info = _nextDate;
}

// Shifts the dates to the right
- (void)setPreviousDates {
    [_nextDateView displayBookings:[_bookingsDictionary objectForKey:_nextDate]];
    [_currentDateView displayBookings:[_bookingsDictionary objectForKey:_selectedDate]];
    [horizontalScrollView setContentOffset:CGPointMake(self.view.width, 0) animated:NO];
    [_previousDateView displayBookings:[_bookingsDictionary objectForKey:_previousDate]];
}

// Shifts the dates to the left
- (void)setNextDates {
    [_previousDateView displayBookings:[_bookingsDictionary objectForKey:_previousDate]];
    [_currentDateView displayBookings:[_bookingsDictionary objectForKey:_selectedDate]];
    [horizontalScrollView setContentOffset:CGPointMake(self.view.width, 0) animated:NO];
    [_nextDateView displayBookings:[_bookingsDictionary objectForKey:_nextDate]];
}

- (void)setDatesForTicket:(Ticket *)ticket {
    if (_allDates) {
        // All dates
        _allDates = NO;
        [_previousDateView displayBookings:[_bookingsDictionary objectForKey:_previousDate]];
        [_currentDateView displayBookings:[_bookingsDictionary objectForKey:_selectedDate]];
        [_nextDateView displayBookings:[_bookingsDictionary objectForKey:_nextDate]];
    } else {
        if (ticket.info == _previousDate) {
            // Previous date
            [self setPreviousDates];
        } else {
            // Previous
            [self setNextDates];
        }
    }
}
- (void)handleCalendarBookingOperation:(Booking *)booking {
    if ([[BookingsManager instance] bookingIsInCalendar:booking]) {
        // Delete booking
        [[BookingsManager instance] deleteBookingFromCalendar:booking];
        [_selectedBookingCloud setBooking:_selectedBookingCloud.booking];
    } else {
        EKEventStore *es = [[EKEventStore alloc] init];
        if ([es respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
            // IOS 6
            [es requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
                /* This code will run when uses has made his/her choice */
                if (granted) {
                    // Add Booking
                    [self performSelectorOnMainThread:@selector(addBookingInCalendarWithEKEventViewController:) withObject:booking waitUntilDone:NO];
                }
            }];
        } else {
            // Add Booking
            [self addBookingInCalendarWithEKEventViewController:booking];
        }
    }
}

- (void)goToToday {
    if ([Utils date:_selectedDate compareTo:[NSDate date]] != NSOrderedSame) {
        _selectedDate = [NSDate date];
        selectedDateButton.title = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
        [self getDates];
    }
}

- (void)addBookingInCalendarWithEKEventViewController:(Booking *)booking {
    EKEventEditViewController *eventViewController = [EKEventEditViewController new];
    EKEventStore *eventStore = [[EKEventStore alloc] init];
    EKEvent *event  = [EKEvent eventWithEventStore:eventStore];
    // Title
    event.title = [NSString stringWithFormat:@"%@ (%@)", booking.course.courseName, booking.typeOfClass.name];
    
    // Start Date
    event.startDate = booking.startDate;
    event.endDate = booking.endDate;
    
    // Teacher + Study groups
    event.notes = [NSString stringWithFormat:@"%@ %@\n%@", booking.teacher.firstName, booking.teacher.lastName, [[BookingsManager instance] stringWithBookingStudyGroups:booking.studyGroups]];
    
    // Location
    event.location = [NSString stringWithFormat:@"%@, %@", booking.room.name, booking.room.building.name];
    
    [event setCalendar:[eventStore defaultCalendarForNewEvents]];
    
    eventViewController.event = event;
    eventViewController.eventStore = eventStore;
    
    eventViewController.editViewDelegate = self;
    [self.navigationController presentModalViewController:eventViewController animated:YES];
}

#pragma mark - Did Finish Editing
- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action {
    if (action == EKEventEditViewActionSaved) {
        [[BookingsManager instance] saveIdentifier:controller.event forBooking:_selectedBookingCloud.booking];
    }
    [controller dismissModalViewControllerAnimated:YES];
    [_selectedBookingCloud setBooking:_selectedBookingCloud.booking];
}

#pragma mark - UpdateBookingDelegate Methods

- (void)didFinishUpdatingBooking:(UpdateBookingViewController *)updateBookingViewController refreshBookings:(BOOL)refreshBookings {
    [updateBookingViewController.navigationController dismissModalViewControllerAnimated:YES];
    if (refreshBookings) {
        [self getDates];
    }
}

#pragma mark - UI Interaction

- (IBAction)dateButtonPressed:(id)sender {
    // We will init the logic and the kalView every time deliveryDateButton is pressed and we will release them when the OK button on the calendarPopOver is pressed
    if (kalView == nil) {
        logic = [[KalLogic alloc] initForDate:_selectedDate];
        kalView = [[KalView alloc] initWithFrame:CGRectMake(0, KAL_VIEW_Y, KAL_VIEW_WIDTH, KAL_VIEW_HEIGHT) delegate:self logic:logic allDays:YES];
    }
    if (!IS_IPAD()) {
        // Lock the PanelViewController and animate the calendarPopOver up
        [calendarPopOver addSubview:kalView];
        UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
        [[mainWindow viewWithTag:1] setUserInteractionEnabled:NO];
        
        [mainWindow addSubview:calendarPopOver];
        calendarPopOver.top = mainWindow.bottom;
        
        [UIView animateWithDuration:0.3
                         animations:^(void)  {
                             calendarPopOver.top -= calendarPopOver.height;
                         }];
    } else {
        // iPad
        UIViewController *viewController = [UIViewController new];
        kalView.top = 0;
        kalView.autoresizingMask = UIViewAutoresizingNone;
        [viewController.view addSubview:kalView];
        viewController.view.backgroundColor = [Utils colorWithHexString:[[ConfigurationManager instance] UIConfigValueForKey:@"calendar_background_color"]];
        viewController.contentSizeForViewInPopover = CGSizeMake(kalView.width, kalView.height + 28);
        ipadPopOverController = [[UIPopoverController alloc] initWithContentViewController:viewController];
        ipadPopOverController.popoverContentSize = CGSizeMake(kalView.width, kalView.height + 28);
        [ipadPopOverController presentPopoverFromRect:CGRectMake(self.view.center.x, self.view.center.y, 1, 1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
        ipadPopOverController.delegate = self;
    }
}

- (IBAction)okPressedOnCalendar:(id)sender {
    UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
    [[mainWindow viewWithTag:1] setUserInteractionEnabled:YES];
    [UIView animateWithDuration:0.3
                     animations:^(void)  {
                         calendarPopOver.top = mainWindow.bottom;
                     } completion:^(BOOL finished) {
                         [calendarPopOver removeFromSuperview];
                     }];
    if (sender != nil) {
        if ([Utils date:_selectedDate compareTo:kalView.selectedDate.NSDate] != NSOrderedSame) {
            _selectedDate = kalView.selectedDate.NSDate;
            selectedDateButton.title = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
            [self getDates];
        }
    }
    
}

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    if ([Utils date:_selectedDate compareTo:kalView.selectedDate.NSDate] != NSOrderedSame) {
        _selectedDate = kalView.selectedDate.NSDate;
        [self getDates];
    }
}

#pragma mark - UIScrollView Delegate Methods
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    if (scrollView.contentOffset.x == 0) {
        // Get Previous date
        _nextDate = _selectedDate;
        _selectedDate = _previousDate;
        _previousDate = [_selectedDate previousDay];
        selectedDateButton.title = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
        
        if ([_bookingsDictionary objectForKey:_previousDate] != nil) {
            [self setPreviousDates];
        } else {
            [Utils showLoadingOn:self];
            _requestsCounter++;
            [[BookingsManager instance] getBookingsForRoom:_room withDate:_previousDate delegate:self].info = _previousDate;
        }
    } else if (scrollView.contentOffset.x == 2 * self.view.width) {
        // Get Next Date
        _previousDate = _selectedDate;
        _selectedDate = _nextDate;
        _nextDate = [_selectedDate nextDay];
        selectedDateButton.title = [Utils stringFromDate:_selectedDate withFormat:DATE_FORMAT];
        if ([_bookingsDictionary objectForKey:_nextDate] != nil) {
            [self setNextDates];
        } else {
            [Utils showLoadingOn:self];
            _requestsCounter++;
            [[BookingsManager instance] getBookingsForRoom:_room withDate:_nextDate delegate:self].info = _nextDate;
        }
    }
}


#pragma mark - Calendar Delegate
- (void)didSelectDate:(KalDate *)date {
    // We only set the date when OK was pressed on the calendar
}

- (void)showFollowingMonth {
    [logic advanceToFollowingMonth];
    [kalView slideDown];
}

- (void)showPreviousMonth {
    [logic retreatToPreviousMonth];
    [kalView slideUp];
}


#pragma mark - BookingsProtocol Methods

- (void)didReceiveBookingsWithSuccess:(id)object forTicket:(Ticket *)ticket {
    if (object != nil) {
        [_bookingsDictionary setValue:object forKey:ticket.info];
    }
    else {
        [_bookingsDictionary removeObjectForKey:ticket.info];
    }
    
    _requestsCounter--;
    if (_requestsCounter == 0) {
        [Utils hideLoadingOn:self];
        [self setDatesForTicket:ticket];
    }
}

- (void)didReceiveBookingsWithFailure:(id)object forTicket:(Ticket *)ticket {
    _requestsCounter--;
    if (_requestsCounter == 0) {
        [Utils hideLoadingOn:self];
        [self setDatesForTicket:ticket];
        WSError *error = (WSError *)object;
        if (error.errorCode == StatusCodeConnectionError) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) otherButtonTitles:NSLocalizedString(@"ALERT_RETRY", nil), nil];
            [alertView show];
        } else {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:error.errorMessage delegate:nil cancelButtonTitle:NSLocalizedString(@"ALERT_OK", nil) otherButtonTitles: nil];
            [alertView show];
        }
    }
}

#pragma mark - UIAlertViewDelegate Methods

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex != alertView.cancelButtonIndex) {
        // Get Study Groups
        [self getDates];
    }
}

#pragma mark - BookingCloudDelegate

- (void)didSelectBookingCloud:(id)sender {
    _selectedBookingCloud = (BookingCloud *)sender;
    Booking *_selectedBooking = _selectedBookingCloud.booking;
    
    if ([_selectedBooking.startDate compare:[NSDate date]] == NSOrderedDescending) {
        // Booking is still available
        NSString *firstButtonName = NSLocalizedString(@"BOOKING_SHEET_ADD_TO_CAL", nil);
        if ([[BookingsManager instance] bookingIsInCalendar:_selectedBooking]) {
            // Booking is already in calendar
            firstButtonName = NSLocalizedString(@"BOOKING_SHEET_DELETE_FROM_CAL", nil);
        }
        if (_selectedBooking.teacher.teacherId == [[[ConfigurationManager instance] applicationConfigValueForKey:USER_ID] integerValue]) {
            // The user can also edit this booking
            UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) destructiveButtonTitle:nil otherButtonTitles:firstButtonName, NSLocalizedString(@"BOOKING_SHEET_CHANGE", nil), nil];
            actionSheet.tag = TEACHER_ACTION_SHEET;
            [actionSheet showInView:self.view];
        } else {
            UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(@"ALERT_CANCEL", nil) destructiveButtonTitle:nil otherButtonTitles:firstButtonName, nil];
            actionSheet.tag = REGULAR_USER_ACTION_SHEET;
            [actionSheet showInView:self.view];
        }
    }
}

#pragma  mark - Action Sheet Delegate Methods

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    
    if (actionSheet.tag == REGULAR_USER_ACTION_SHEET) {
        // Regular user action sheet
        if (buttonIndex != actionSheet.cancelButtonIndex) {
            [self handleCalendarBookingOperation:_selectedBookingCloud.booking];
        }
    } else if (actionSheet.tag == TEACHER_ACTION_SHEET) {
        // Teacher action sheet
        if (buttonIndex == 0) {
            // Handle booking in calendar
            [self handleCalendarBookingOperation:_selectedBookingCloud.booking];
        } else if (buttonIndex != actionSheet.cancelButtonIndex) {
            // Update booking
            UpdateBookingViewController *updateBooking = [[UpdateBookingViewController alloc] initWithNibName:@"UpdateBookingViewController" booking:_selectedBookingCloud.booking course:nil];
            updateBooking.delegate = self;
            updateBooking.title = _selectedBookingCloud.booking.course.courseName;
            updateBooking.updatingBooking = YES;
            UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:updateBooking];
            [self.navigationController presentModalViewController:navigationController animated:YES];
        }
    }
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidUnload {
    [self setDateToolbar:nil];
    [self setDateButton:nil];
    [self setSelectedDateButton:nil];
    [self setHorizontalScrollView:nil];
    calendarPopOver = nil;
    [super viewDidUnload];
}
@end
